//
//  GGNetWorkTool.m
//  cicada
//
//  Created by iOSer on 2016/12/14.
//  Copyright © 2016年 iOSer. All rights reserved.
//

#import "GGNetWorkTool.h"
#import <CommonCrypto/CommonDigest.h>

@interface GGNetWorkTool()

@end
@implementation GGNetWorkTool


+(instancetype)sharedTools{
    static GGNetWorkTool *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{
        
        instance = [[GGNetWorkTool alloc] init];

    });
    return instance;
}




- (GGResponseResult *)requestWithMethod:(RequestMethod)method
                urlString:(NSString *)url
               parameters:(NSDictionary *)parameters
     CacheTimeoutInterval:(NSInteger)timeoutInterval
                 progress:(void (^)(GGResponseResult *result))Progress
                  success:(void (^)(GGResponseResult *result))success
                  failure:(void(^)(GGResponseResult *result))failure {
    
    //----公共参数处理----//
    __block NSString *urlString = nil;
    __block NSDictionary *paramter = nil;
    
    //----URL处理----//
    urlString = [self isURLAutoEncode]?[GGNetWorkHelper urlEncode:urlString]:urlString;
    //----请求头处理----//
//    [self.connector.requestSerializer setValue:value forHTTPHeaderField:httpHeaderField];
    
    //----超时处理----//
    /* 判断是否超时
     * 超时规则:超时或不缓存(0)都为超时
     */
    BOOL timeOut = [GGNetWorkHelper dataCacheTimeoutWithInterval:timeoutInterval URL:urlString parameters:paramter];
    GGResponseResult *allResult;
    if (timeOut == YES) {
        switch (method) {
            case GET:
                {
                    allResult = [self GETRequestWithURL:urlString parameters:paramter CacheTimeoutInterval:timeoutInterval progress:Progress success:success failure:failure];
                }
                break;
            case POST:
            {
                
                allResult = [self POSTRequestWithURL:urlString parameters:paramter CacheTimeoutInterval:timeoutInterval progress:Progress success:success failure:failure];
            }
                break;
            default:
                break;
        }
    }else{
        //如果不超时则构造返回体
        GGResponseResult *result = [[GGResponseResult alloc] init];
        id responseCache = [GGNetWorkCache netWorkCacheForURL:urlString parameters:paramter];
        result.resultStateType = GGResponseResultTypeSuccess;
        result.responseObject = responseCache;
        result.responseCache = responseCache;
        if (success) {
            success(result);
        }
    }
    return allResult;
}

#pragma mark - GET请求
-(GGResponseResult *)GETRequestWithURL:(NSString *)url
              parameters:(NSDictionary *)parameters
    CacheTimeoutInterval:(NSInteger)timeoutInterval
                progress:(void (^)(GGResponseResult *result))Progress
                 success:(void (^)(GGResponseResult *result))success
                 failure:(void(^)(GGResponseResult *result))failure{
    
    id responseCache = nil;
    
   NSURLSessionDataTask *task = [self.connector GET:url parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
        
        if (Progress) {
            GGResponseResult *result = [GGResponseResult new];
            result.downLoadProgress = downloadProgress;
            Progress(result);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        if (success) {
            
            [self connectCompleteHandleWithResult:YES Method:GET URL:[task.response.URL absoluteString] Params:parameters Response:responseObject TimeoutInterval:timeoutInterval];
            GGResponseResult *result = [GGResponseResult resultWithTask:task responseObject:responseObject];
            result.responseCache = responseCache;
            success(result);
        }
       
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (failure) {
            
            GGResponseResult *result = [GGResponseResult resultWithTask:task error:error];
            result.responseCache = responseCache;
            [self connectCompleteHandleWithResult:NO Method:GET URL:[task.response.URL absoluteString] Params:parameters Response:error TimeoutInterval:timeoutInterval];
            failure(result);
        }
        
    }];
    
    GGResponseResult *allResult = [GGResponseResult new];
    allResult.task = task;
    return allResult;
}

-(GGResponseResult *)POSTRequestWithURL:(NSString *)url
               parameters:(NSDictionary *)parameters
     CacheTimeoutInterval:(NSInteger)timeoutInterval
                 progress:(void (^)(GGResponseResult *result))Progress
                  success:(void (^)(GGResponseResult *result))success
                  failure:(void(^)(GGResponseResult *result))failure{
    
    id responseCache = nil;
   NSURLSessionDataTask *task = [self.connector POST:url parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
        if (Progress) {
            GGResponseResult *result = [GGResponseResult new];
            result.uploadProgress = uploadProgress;
            Progress(result);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            
            [self connectCompleteHandleWithResult:YES Method:POST URL:[task.response.URL absoluteString] Params:parameters Response:responseObject TimeoutInterval:timeoutInterval];
            GGResponseResult *result = [GGResponseResult resultWithTask:task responseObject:responseObject];
            result.responseCache = responseCache;
            success(result);
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (failure) {
            
            GGResponseResult *result = [GGResponseResult resultWithTask:task error:error];
            result.responseCache = responseCache;
            
            [self connectCompleteHandleWithResult:NO Method:POST URL:[task.response.URL absoluteString] Params:parameters Response:error TimeoutInterval:timeoutInterval];
            failure(result);
        }
        
    }];
    GGResponseResult *allResult = [GGResponseResult new];
    allResult.task = task;
    return allResult;
    
}

- (GGResponseResult *)uploadWithUrlStr:(NSString *)url
              parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                progress:(void (^)(GGResponseResult *result))Progress
                 success:(void (^)(GGResponseResult *result))success
                 failure:(void(^)(GGResponseResult *result))failure {
    
    
    //****公共参数****//
    
    //判断是否开启自动编码
    url = [self isURLAutoEncode]?[GGNetWorkHelper urlEncode:url]:url;
    
    //头部添加RSA
    
   NSURLSessionDataTask *task = [self.connector POST:url parameters:parameters constructingBodyWithBlock:block progress:^(NSProgress * _Nonnull uploadProgress) {
        
        if (Progress) {
            GGResponseResult *result = [GGResponseResult new];
            result.uploadProgress = uploadProgress;
            Progress(result);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            
             GGResponseResult *result = [GGResponseResult resultWithTask:task responseObject:responseObject];
            success(result);
        }
       
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failure) {
             GGResponseResult *result = [GGResponseResult resultWithTask:task error:error];
            failure(result);
        }
        
    }];
    GGResponseResult *allResult = [GGResponseResult new];
    allResult.task = task;
    return allResult;
}

- (void)connectCompleteHandleWithResult:(BOOL)isSuccess Method:(RequestMethod)requestMethod URL:(NSString *)url Params:(NSDictionary *)params Response:(id)response  TimeoutInterval:(NSInteger)timeoutInterval{
    //判断是否开启DEBUGLOG
    if ([self isDebugLog]) {
        [self logWithResults:isSuccess
               RequestMethod:requestMethod Response:response url:url params:params];
    }
    //失败不更新缓存
    if (isSuccess) {
        //判断是否开启缓存
        if (timeoutInterval != 0) {
            //如果开启缓存,更新缓存时间
            //如果返回数据不为空,则根据URL和param缓存数据
            [GGNetWorkCache setNetWorkCacheTimeWithURL:url parameters:params];
            response!=nil ? [GGNetWorkCache setNetWorkCacheWithData:response URL:url parameters:params] : nil;
        }
    }
    
}

- (void)logWithResults:(BOOL)isSuccess
         RequestMethod:(RequestMethod)requestMethod
              Response:(id)response
                   url:(NSString *)url
                params:(NSDictionary *)params {
    
    MLog(@"\n");
    MLog(@"\n******请求%@******\n URL: %@\n 请求类型:%@\n 请求头:%@\n 参数:%@\n 返回值:%@\n\n",
          isSuccess?@"成功":@"失败",
          url,
          requestMethod == GET?@"GET":@"POST",
          self.connector.requestSerializer.HTTPRequestHeaders,
          params,
          [GGNetWorkHelper tryToParseData:response]);
}



//sign加密处理
-(NSString *)appSignWithAppID:(NSString *)appid andTimestamp:(NSString *)timestamp andAppsecret:(NSString *)appsecret{
    //NSString *app_sign = [NSString stringWithFormat:@"%@%@%@",appid,timestamp,appsecret];
    NSString *app_signSha = @"";
    NSString *sign = [app_signSha uppercaseString];
    return sign;
}


- (BOOL)isDebugLog {
    return IS_NETWORK_DEBUGLOG;
}

- (BOOL)isURLAutoEncode{
    return IS_URL_AUTO_ENCODE;
}

-(GGNetWorkConnector *)connector{
    if (!_connector) {
        _connector = [GGNetWorkConnector sharedConnector];
    }
    return _connector;
}

@end
